<!DOCTYPE html>
<html>
<head>
    <title>Relativity Diagram</title>
</head>
<body>
    <canvas id="physicsCanvas" width="500" height="500" style="border:1px solid #d3d3d3;"></canvas>
    <script>
        const canvas = document.getElementById('physicsCanvas');
        const ctx = canvas.getContext('2d');

        /**
         * Draws an arrow on the canvas context.
         * @param {CanvasRenderingContext2D} ctx - The canvas rendering context.
         * @param {number} fromx - The x-coordinate of the arrow's start point.
         * @param {number} fromy - The y-coordinate of the arrow's start point.
         * @param {number} tox - The x-coordinate of the arrow's end point.
         * @param {number} toy - The y-coordinate of the arrow's end point.
         * @param {number} [headlen=10] - The length of the arrowhead sides.
         */
        function drawArrow(ctx, fromx, fromy, tox, toy, headlen = 10) {
            const angle = Math.atan2(toy - fromy, tox - fromx);
            // Draw the line
            ctx.beginPath();
            ctx.moveTo(fromx, fromy);
            ctx.lineTo(tox, toy);
            ctx.stroke();
            // Draw the arrowhead
            ctx.beginPath();
            ctx.moveTo(tox, toy);
            ctx.lineTo(tox - headlen * Math.cos(angle - Math.PI / 6), toy - headlen * Math.sin(angle - Math.PI / 6));
            ctx.lineTo(tox - headlen * Math.cos(angle + Math.PI / 6), toy - headlen * Math.sin(angle + Math.PI / 6));
            ctx.closePath();
            ctx.fill();
        }

        /**
         * Draws a filled circle representing a point.
         * @param {CanvasRenderingContext2D} ctx - The canvas rendering context.
         * @param {number} x - The x-coordinate of the point.
         * @param {number} y - The y-coordinate of the point.
         * @param {number} [radius=3.5] - The radius of the point.
         */
        function drawPoint(ctx, x, y, radius = 3.5) {
            ctx.beginPath();
            ctx.arc(x, y, radius, 0, 2 * Math.PI);
            ctx.fill();
        }

        // --- Main Drawing ---

        // Style setup
        ctx.strokeStyle = 'black';
        ctx.fillStyle = 'black';
        ctx.lineWidth = 1.5;
        
        // Define coordinates and dimensions
        const origin = { x: 200, y: 250 };
        const axisXStart = origin.x - 50;
        const axisXEnd = origin.x + 250;
        const axisYStart = origin.y + 220;
        const axisYEnd = origin.y - 220;
        const l = 150;
        const dist1 = 70;
        const dist2 = 120;
        const dist3 = 120;
        const v_len = 30;

        // Draw Axes
        drawArrow(ctx, axisXStart, origin.y, axisXEnd, origin.y);
        drawArrow(ctx, origin.x, axisYStart, origin.x, axisYEnd);
        
        // Label Axes and Origin
        ctx.font = 'italic 24px Times New Roman';
        ctx.fillText('y', origin.x + 8, axisYEnd + 10);
        ctx.fillText('x', axisXEnd + 5, origin.y + 8);
        ctx.fillText('O', origin.x - 25, origin.y + 10);
        drawPoint(ctx, origin.x, origin.y, 3);
        
        // S Frame Label
        ctx.font = '28px Times New Roman';
        ctx.fillText('S系', origin.x + 200, origin.y - 150);

        // Point P
        const p_pos = { x: origin.x, y: origin.y - l };
        drawPoint(ctx, p_pos.x, p_pos.y);
        ctx.font = 'italic 22px Times New Roman';
        ctx.fillText('P', p_pos.x - 25, p_pos.y + 8);
        ctx.fillText('y=l', p_pos.x + 15, p_pos.y + 8);

        // Point 1 and velocity
        const p1_pos = { x: origin.x, y: origin.y - dist1 };
        drawPoint(ctx, p1_pos.x, p1_pos.y, 4);
        ctx.font = '22px Arial';
        ctx.fillText('1', p1_pos.x - 25, p1_pos.y + 8);
        drawArrow(ctx, p1_pos.x, p1_pos.y, p1_pos.x, p1_pos.y - v_len);
        ctx.font = 'italic 22px Times New Roman';
        ctx.fillText('v', p1_pos.x + 10, p1_pos.y - v_len / 2 + 5);

        // Point 2 and velocity
        const p2_pos = { x: origin.x, y: origin.y + dist2 };
        drawPoint(ctx, p2_pos.x, p2_pos.y, 4);
        ctx.font = '22px Arial';
        ctx.fillText('2', p2_pos.x - 25, p2_pos.y + 8);
        drawArrow(ctx, p2_pos.x, p2_pos.y, p2_pos.x, p2_pos.y + v_len);
        ctx.font = 'italic 22px Times New Roman';
        ctx.fillText('v', p2_pos.x + 10, p2_pos.y + v_len / 2 + 5);

        // Point 3 and velocity
        const p3_pos = { x: origin.x + dist3, y: origin.y };
        drawPoint(ctx, p3_pos.x, p3_pos.y, 4);
        ctx.font = '22px Arial';
        ctx.fillText('3', p3_pos.x - 5, p3_pos.y + 25);
        const v3_start = { x: p3_pos.x + 10, y: origin.y };
        const v3_end = { x: v3_start.x + v_len + 10, y: v3_start.y };
        drawArrow(ctx, v3_start.x, v3_start.y, v3_end.x, v3_end.y);
        ctx.font = 'italic 22px Times New Roman';
        ctx.fillText('v', v3_start.x + (v3_end.x - v3_start.x)/2 - 5, v3_start.y - 10);

    </script>
</body>
</html>